﻿using D20;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
namespace D20.UnitTests.Characters
{


    /// <summary>
    ///This is a test class for DiceRollTest and is intended
    ///to contain all DiceRollTest Unit Tests
    ///</summary>
    [TestClass()]
    public class DiceRollTest
    {


        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion


        /// <summary>
        ///A test for ToString
        ///</summary>
        [TestMethod()]
        public void ToStringTest()
        {
            DiceRoll target = new DiceRoll(1, 2, -3); 
            string expected = "1d2 - 3"; 
            string actual;
            actual = target.ToString();
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for Roll
        ///</summary>
        [TestMethod()]
        public void RollTest()
        {
            for (int i = 0; i < 5000; i++)
            {
                checked
                {
                    int numberOfDie = r.Next(-100, 100);
                    int sidesPerDie = r.Next(-1000, 1000);
                    if (numberOfDie <= 0 || sidesPerDie <= 0)
                    {
                        try
                        {
                            new DiceRoll(numberOfDie, sidesPerDie, r.Next(-50000, 50000));
                        }
                        catch (ArgumentOutOfRangeException)
                        {
                            continue;
                        }
                    }
                    DiceRoll target = new DiceRoll(numberOfDie, sidesPerDie, r.Next(-50000, 50000));
                    int expectedMin = target.MinimumOutcome;
                    int expectedMax = target.MaximumOutcome;
                    if (target.NumberOfDie <= 0 || target.SidesPerDie <= 0)
                    {
                        try
                        {
                            target.Roll();
                        }
                        catch (ArgumentOutOfRangeException)
                        {
                            continue;
                        }
                    }
                    int actual = target.Roll();
                    Assert.IsTrue(actual >= expectedMin, "actual >= expectedMin; actual = {0}, expectedMin = {1}", actual, expectedMin);
                    Assert.IsTrue(actual <= expectedMax, "actual <= expectedMax; actual = {0}, expectedMax = {1}", actual, expectedMax);
                }
            }
        }

        /// <summary>
        ///A test for op_Inequality
        ///</summary>
        [TestMethod()]
        public void op_InequalityTest()
        {
            for (int i = 0; i < 1000; i++)
            {
                DiceRoll left = new DiceRoll(r.Next(1, 100), r.Next(1, 1000), r.Next(-50000, 50000));
                DiceRoll right = new DiceRoll();
                right.NumberOfDie = left.NumberOfDie + 1;
                right.SidesPerDie = left.SidesPerDie;
                right.Modifier = left.Modifier;
                Assert.IsTrue(left != right);
            }
            for (int i = 0; i < 1000; i++)
            {
                DiceRoll left = new DiceRoll(r.Next(1, 100), r.Next(1, 1000), r.Next(-50000, 50000));
                DiceRoll right = new DiceRoll();
                right.NumberOfDie = left.NumberOfDie;
                right.SidesPerDie = left.SidesPerDie;
                right.Modifier = left.Modifier;
                Assert.IsFalse(left != right);
            }
        }

        /// <summary>
        ///A test for op_Equality
        ///</summary>
        [TestMethod()]
        public void op_EqualityTest()
        {
            for (int i = 0; i < 1000; i++)
            {
                DiceRoll left = new DiceRoll(r.Next(1, 100), r.Next(1, 1000), r.Next(-50000, 50000));
                DiceRoll right = new DiceRoll();
                right.NumberOfDie = left.NumberOfDie;
                right.SidesPerDie = left.SidesPerDie;
                right.Modifier = left.Modifier;
                Assert.IsTrue(left == right);
            }
            for (int i = 0; i < 1000; i++)
            {
                DiceRoll left = new DiceRoll(r.Next(1, 100), r.Next(1, 1000), r.Next(-50000, 50000));
                DiceRoll right = new DiceRoll();
                right.NumberOfDie = left.NumberOfDie + 1;
                right.SidesPerDie = left.SidesPerDie;
                right.Modifier = left.Modifier;
                Assert.IsFalse(left == right);
            }
        }

        /// <summary>
        ///A test for op_Addition
        ///</summary>
        [TestMethod()]
        public void op_AdditionTest2()
        {
            for (int i = 0; i < 1000; i++)
            {
                DiceRoll left = new DiceRoll(r.Next(1, 100), r.Next(1, 1000), r.Next(-50000, 50000));
                int right = r.Next(100000);
                int expectedMin = left.MinimumOutcome + right;
                int expectedMax = left.MaximumOutcome + right;
                int actual;
                actual = (left + right);
                Assert.IsTrue(actual >= expectedMin, "actual >= expectedMin");
                Assert.IsTrue(actual <= expectedMax, "actual <= expectedMax");
            }
        }

        /// <summary>
        ///A test for op_Addition
        ///</summary>
        [TestMethod()]
        public void op_AdditionTest1()
        {
            for (int i = 0; i < 1000; i++)
            {
                int left = r.Next(100000);
                DiceRoll right = new DiceRoll(r.Next(1, 100), r.Next(1, 1000), r.Next(-50000, 50000));
                int expectedMin = left + right.MinimumOutcome;
                int expectedMax = left + right.MaximumOutcome;
                int actual;
                actual = (left + right);
                Assert.IsTrue(actual >= expectedMin, "actual >= expectedMin");
                Assert.IsTrue(actual <= expectedMax, "actual <= expectedMax");
            }
        }
        Random r = new Random();
        /// <summary>
        ///A test for op_Addition
        ///</summary>
        [TestMethod()]
        public void op_AdditionTest()
        {
            for (int i = 0; i < 1000; i++)
            {
                DiceRoll left = new DiceRoll(r.Next(1, 100), r.Next(1, 1000), r.Next(-50000, 50000));
                DiceRoll right = new DiceRoll(r.Next(1, 100), r.Next(1, 1000), r.Next(-50000, 50000));
                int expectedMin = left.MinimumOutcome + right.MinimumOutcome;
                int expectedMax = left.MaximumOutcome + right.MaximumOutcome;
                int actual;
                actual = (left + right);
                Assert.IsTrue(actual >= expectedMin, "actual >= expectedMin");
                Assert.IsTrue(actual <= expectedMax, "actual <= expectedMax");
            }
        }

        /// <summary>
        ///A test for Equals
        ///</summary>
        [TestMethod()]
        public void EqualsTest()
        {
            DiceRoll target = new DiceRoll(1,3,4);
            object obj = new DiceRoll(1,3,4);
            bool expected = true; 
            bool actual;
            actual = target.Equals(obj);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for Add
        ///</summary>
        [TestMethod()]
        public void AddTest2()
        {
            for (int i = 0; i < 1000; i++)
            {
                DiceRoll left = new DiceRoll(r.Next(1, 100), r.Next(1, 1000), r.Next(-50000, 50000));
                int right = r.Next(100000);
                int expectedMin = left.MinimumOutcome + right;
                int expectedMax = left.MaximumOutcome + right;
                int actual;
                actual = DiceRoll.Add(left, right);
                Assert.IsTrue(actual >= expectedMin, "actual >= expectedMin");
                Assert.IsTrue(actual <= expectedMax, "actual <= expectedMax");
            }
        }

        /// <summary>
        ///A test for Add
        ///</summary>
        [TestMethod()]
        public void AddTest1()
        {
            for (int i = 0; i < 1000; i++)
            {
                int left = r.Next(100000);
                DiceRoll right = new DiceRoll(r.Next(1, 100), r.Next(1, 1000), r.Next(-50000, 50000));
                int expectedMin = left + right.MinimumOutcome;
                int expectedMax = left + right.MaximumOutcome;
                int actual;
                actual = DiceRoll.Add(left, right);
                Assert.IsTrue(actual >= expectedMin, "actual >= expectedMin");
                Assert.IsTrue(actual <= expectedMax, "actual <= expectedMax");
            }
        }

        /// <summary>
        ///A test for Add
        ///</summary>
        [TestMethod()]
        public void AddTest()
        {
            for (int i = 0; i < 1000; i++)
            {
                DiceRoll left = new DiceRoll(r.Next(1, 100), r.Next(1, 1000), r.Next(-50000, 50000));
                DiceRoll right = new DiceRoll(r.Next(1, 100), r.Next(1, 1000), r.Next(-50000, 50000));
                int expectedMin = left.MinimumOutcome + right.MinimumOutcome;
                int expectedMax = left.MaximumOutcome + right.MaximumOutcome;
                int actual;
                actual = DiceRoll.Add(left, right);
                Assert.IsTrue(actual >= expectedMin, "actual >= expectedMin");
                Assert.IsTrue(actual <= expectedMax, "actual <= expectedMax");
            }
        }
    }
}
